package com.chen.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.chen.common.VIP;
import com.chen.dao.mapper.CourseMapper;
import com.chen.dao.pojo.Coach;
import com.chen.dao.pojo.Course;
import com.chen.dao.pojo.CourseRecord;
import com.chen.dao.pojo.User;
import com.chen.service.CoachService;
import com.chen.service.CourseRecordService;
import com.chen.service.CourseService;
import com.chen.service.UserService;
import com.chen.util.DateUtils;
import com.chen.vo.CourseVo;
import com.chen.vo.Result;
import com.chen.vo.param.CourseParam;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @Author:chenao
 * @DATE:2022/3/19 14:58
 */
@Service
public class CourseServiceImpl implements CourseService {

    @Autowired
    private CourseMapper courseMapper;
    @Autowired
    private CoachService coachService;
    @Autowired
    private UserService userService;
    @Autowired
    private CourseRecordService courseRecordService;

    private final static String formatPattern="yyyy-MM-dd HH:mm:ss";

    @Override
    public Result listCourse(CourseParam param) {
        LambdaQueryWrapper<Course> wrapper = new LambdaQueryWrapper<>();
        //代表返回属于教练的课程
        if (Strings.isNotBlank(param.getCoachId())){
            wrapper.eq(Course::getCoachId,param.getCoachId());
        }
        if (Strings.isNotBlank(param.getCourseName())){
            wrapper.like(Course::getCourseName,param.getCourseName());
        }
        List<Course> courses = courseMapper.selectList(wrapper);
        List<CourseVo> courseVoList = new LinkedList<>();

        if (Strings.isNotBlank(param.getDate())) {
            DateTime chooseDate = DateUtil.parse(param.getDate(), "yyyy/MM/dd");
            courses = courses.stream().filter(item -> {
                DateTime startTime = DateUtil.parse(item.getStartTime(), formatPattern);
                return DateUtil.isSameDay(startTime, chooseDate);
            }).collect(Collectors.toList());
        }

        courses.stream().forEach(item -> {
            CourseVo courseVo = new CourseVo();
            BeanUtils.copyProperties(item, courseVo);
            Coach coach = coachService.findCoachById(item.getCoachId());
            courseVo.setCoachName(coach.getName());
            courseVo.setCoachIntroduce(coach.getIntroduce());
            courseVo.setCoachAuth(coach.getCoachAuth());
            courseVo.setTime(DateUtils.formatCourseTime(item));
            courseVo.setCoachAvatar(coach.getAvatar());
            courseVoList.add(courseVo);
        });
        return Result.success(courseVoList);
    }

    @Override
    public Result findCourseDetail(CourseParam param) {
        Course course = courseMapper.selectById(param.getId());
        CourseVo courseVo = new CourseVo();
        String endTime = course.getEndTime();
        DateTime endDate = DateUtil.parse(endTime, formatPattern);
        if (endDate.getTime()<new Date().getTime()){
            //代表已经过了课程时间段
            courseVo.setExpired(true);
        }
        BeanUtils.copyProperties(course, courseVo);
        Coach coach = coachService.findCoachById(course.getCoachId());
        courseVo.setCoachName(coach.getName());
        courseVo.setCoachIntroduce(coach.getIntroduce());
        courseVo.setCoachAuth(coach.getCoachAuth());
        courseVo.setTime(DateUtils.formatCourseTime(course));
        courseVo.setCoachAvatar(coach.getAvatar());
        return Result.success(courseVo);
    }

    @Override
    public Result reserveCourse(CourseParam param) {
        User user = userService.queryUserById(param.getUserId());
        Course course = courseMapper.selectById(param.getId());
        //课程剩余人数
        Integer personNum = Integer.valueOf(course.getPersonNum());
        if (user == null || course == null) {
            return Result.fail(10000, "参数错误");
        }
        if (courseRecordService.isRecord(param.getUserId(),param.getId())){
            return Result.fail(10001,"您已经预约了该课程，不可重复预约");
        }
        if (Integer.valueOf(course.getPersonNum())<=0){
            return Result.fail(10002,"课程人数已满");
        }
        personNum--;
        //获取用户的会员类型
        String category = user.getCategory();
        Integer balance = user.getBalance();
        //截止日期，格式为yyyy-MM-dd HH:mm:ss
        String deadline = user.getDeadline();
        Integer overTimes = user.getOverTimes();

        CourseRecord courseRecord = new CourseRecord();
        courseRecord.setCourseId(course.getId());
        courseRecord.setUserId(user.getId());
        String formatPattern="yyyy-MM-dd HH:mm:ss";
        courseRecord.setEditTime(DateUtil.format(new Date(), formatPattern));

        if (category.equals(VIP.yearVIP) || category.equals(VIP.monthVIP)){
            if (Strings.isNotBlank(deadline)){
                DateTime deadDate = DateUtil.parse(deadline, formatPattern);
                if ((new Date()).getTime()>deadDate.getTime()){
                    //代表已经过期了，需要修改会员类型
                    category=VIP.timesVip;
                }else {
                    courseRecordService.insertRecord(courseRecord);
                    reducePersonNum(course.getId(),personNum);
                    return Result.success("尊贵的"+category+",您已约课成功");
                }
            }
        }
        if (category.equals(VIP.timesVip)){
            if (overTimes<=0){
                //代表过期，降级为普通会员
                category=VIP.commonVIP;
            }else {
                overTimes--;
                user.setOverTimes(overTimes);
                user.setCategory(category);
                courseRecordService.insertRecord(courseRecord);
                userService.update(user);
                reducePersonNum(course.getId(),personNum);
                return Result.success("尊敬的"+category+",您已约课成功");
            }
        }
        //课程的价格,到这里，说明用户是普通会员，需要判断余额
        Integer price = Integer.valueOf(course.getPrice());
        if (balance!=null && balance>=price){
            balance=balance-price;
            user.setBalance(balance);
            user.setCategory(category);
            //约课成功的同时，消耗余额
            courseRecordService.insertRecord(courseRecord);
            userService.update(user);
            reducePersonNum(course.getId(),personNum);
            return Result.success("您已约课成功");
        }
        //到这一步代表已经是普通会员，且余额不足
        return Result.fail(10002,"对不起，您的余额不足，请联系健身房管理员充值");
    }

    @Override
    public Course getCourseById(String id) {
        LambdaQueryWrapper<Course> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Course::getId,id);
        return courseMapper.selectOne(wrapper);
    }


    /**
     * 用于约课成功之后，减少一个课程剩余余额人数
     * @param id 课程id
     * @param num 需要更新的剩余人数
     */
    private void reducePersonNum(String id,Integer num){
        Course course = new Course();
        course.setId(id);
        course.setPersonNum(String.valueOf(num));
        courseMapper.updateById(course);
    }
}
